<template lang="pug">
  .cropper-box
    .container(v-show="panel")
      .img-div
        img(:id="imgName" :ref="imgName" :src="url")
      .fixed-bottom
        .btn.btn-default(@click="cancel") 取消
        .btn.btn-primary(@click="crop") 确定
    label(:class="labelClass", :for="name")
      div
        input(:id="name" style="display: none;" type="file" :ref="name" @change="change")
        div {{title}}
</template>

<script>
import Cropper from 'cropperjs'
import 'cropperjs/dist/cropper.css'

export default {
  props: {
    title: {
      type: String
    },
    type: {
      type: String,
      default: 'jpg'
    },
    mask: {
      type: Boolean,
      default: false
    },
    maskNormal: {
      type: Boolean,
      default: false
    },
    screenShot: {
      type: Boolean,
      default: true
    },
    name: {
      type: String,
      default: 'change'
    },
    imgName: {
      type: String,
      default: 'img'
    },
    aspectRatio: {
      required: false,
      default: 1
    }
  },
  data () {
    return {
      cropImg: '',
      picValue: '',
      cropper: '',
      croppable: false,
      panel: false,
      url: ''
    }
  },
  computed: {
    labelClass () {
      if (this.maskNormal) {
        return 'mask-normal'
      } else if (this.mask) {
        return 'mask'
      } else {
        return 'label'
      }
    }
  },
  mounted () {
    let self = this
    this.cropper = new Cropper(this.$refs[this.imgName], {
      aspectRatio: this.aspectRatio,
      viewMode: 1,
      dragMode: 'move',
      background: false,
      ready: function () {
        self.croppable = true
      }
    })
  },
  methods: {
    cancel () {
      this.panel = false
      this.clearImg()
    },
    clearImg () {
      this.$refs[this.name].value = ''
    },
    getObjectURL (file) {
      let url = null
      if (window.createObjectURL !== undefined) {
        url = window.createObjectURL(file)
      } else if (window.URL !== undefined) {
        url = window.URL.createObjectURL(file)
      } else if (window.webkitURL !== undefined) {
        url = window.webkitURL.createObjectURL(file)
      }
      return url
    },
    change (e) {
      const files = e.target.files || e.dataTransfer.files
      if (files.length !== 1) {
        return alert('请选择一张图片')
      }
      const file = files[0]
      if (!/image\/(jpg|jpeg|png)/.test(file.type)) {
        return alert('只支持jpg、png格式')
      }
      const fileSize = file.size / 1024 / 1024
      if (fileSize > 5) {
        return alert('上传图片必须在5M以内')
      }
      if (!files.length) return
      if (this.screenShot) this.panel = true
      this.picValue = files[0]

      this.url = this.getObjectURL(this.picValue)
      if (this.cropper) {
        this.cropper.replace(this.url)
      }
      if (this.screenShot) {
        this.panel = true
      } else {
        this.cropImg = this.picValue
        this.uploadImg()
      }
    },
    crop () {
      const img = new Image()
      const reg = /^https?:\/\//i
      reg.test(this.url) && (img.crossOrigin = 'Anonymous')
      const self = this
      img.onload = function () {
        const canvas = document.createElement('canvas')
        const imgWidth = this.width
        const imgHeight = this.height
        let ratio = 1
        if (imgWidth > 750 || imgHeight > 750) {
          ratio = imgWidth > imgHeight ? 750 / imgWidth : 750 / imgHeight
          canvas.width = imgWidth * ratio
          canvas.height = imgHeight * ratio
        } else {
          canvas.width = imgWidth
          canvas.height = imgHeight
        }
        const context = canvas.getContext('2d')
        context.scale(ratio, ratio)
        context.clearRect(0, 0, canvas.width, canvas.height)
        context.drawImage(img, 0, 0)
        context.restore()
        const result = canvas.toDataURL('image/jpeg')
        self.cropImg = result
        self.clearImg()
        self.uploadImg()
      }

      img.src = this.cropper.getCroppedCanvas().toDataURL('image/jpeg')
      this.panel = false
    },
    async uploadImg () {
      const {code, data} = (await this.$http.post('/manage/image/upload', {
        imgSrc: this.cropImg,
        type: this.type
      })).data
      if (code === 0) {
        this.$emit('save', data)
      } else {
        alert(data.message)
      }
    }
  }
}
</script>

<style scoped lang="stylus">
  .cropper-box
    width 100%
    height 100%

  .mask, .label, .mask-normal
    width 100%
    height 100%
    display flex
    justify-content center
    align-items center
    margin-bottom 0
    cursor pointer

  .mask
    color $reverse-color
    background-color rgba(0, 0, 0, .35)
    border-radius 50%
  .mask-normal
    color $reverse-color
    background-color rgba(0, 0, 0, .35)
  .show
    width 100px
    height 100px
    overflow hidden
    position relative
    border 1px solid #d5d5d5

  .picture
    width 100%
    height 100%
    overflow hidden
    background-position center center
    background-repeat no-repeat
    background-size cover

  .container
    z-index 10001
    position fixed
    left 0
    top 0
    right 0
    bottom 0

  .img-div
    display flex
    align-items center
    height calc(100% - 40px)

  #image
    max-width: 100%

  .opera
    display flex
    position fixed
    bottom 0
    justify-content space-between
    width 80%
    font-size 16px
    color white
    padding 0 10%

  .fixed-bottom
    display flex
    justify-content center
    color #fff
    background-color #000
    opacity 0.5
    border-top 1px solid #fff
</style>
